package com.zmn.oms.task.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.manager.mq.annotation.AliyunMQHandler;
import com.zmn.manager.mq.annotation.AliyunMQListener;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.business.interfaces.callpop.CallRecordBService;
import com.zmn.oms.business.interfaces.xno.OrderTempXnoBindBService;
import com.zmn.oms.business.interfaces.xno.OrderXnoBindBService;
import com.zmn.oms.business.interfaces.xno.OrderXnoBindService;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.common.dto.OmsOperator;
import com.zmn.oms.common.utils.TimeUtils;
import com.zmn.oms.manager.utils.OmsMqTagConsts;
import com.zmn.oms.model.dto.log.CallRecordLogDTO;
import com.zmn.oms.model.dto.work.xno.TempXnoUnBindDTO;
import com.zmn.oms.model.dto.work.xno.XnoBindDTO;
import com.zmn.oms.model.dto.work.xno.XnoUnBindDTO;
import com.zmn.oms.model.vo.work.detail.ZsXnoBindVO;
import com.zmn.xno.common.enums.FinishState;
import com.zmn.xno.common.enums.FinishType;
import com.zmn.xno.model.bo.call.CallRecordToMqBO;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * 类描述：工单隐私小号通话记录保存
 *
 * @author songweidong
 * @date 2020/08/10 16:53
 */
@AliyunMQListener(topic = "${spring.mq.topic.xno}")
@Component
@Slf4j
public class XnoListener {

    private static final Logger logger = LoggerFactory.getLogger(XnoListener.class);

    @Autowired
    private CallRecordBService callRecordBService;
    @Resource
    private OrderXnoBindBService orderXnoBindBService;
    @Autowired
    private OrderXnoBindService orderXnoBindService;
    @Autowired
    private OrderTempXnoBindBService orderTempXnoBindBService;
    @Resource
    private RedisManager redisManager;

    @AliyunMQHandler(tags = OmsMqTagConsts.ZMN_TOPIC_XNO_CALL_RECORD)
    public void callRecord(String message) {
        try {
            logger.info("工单小号通话记录消费[{}]", message);
            // 小号通话记录
            CallRecordToMqBO callRecordToMqBO = JSON.parseObject(message, CallRecordToMqBO.class);
            if (!NumberUtil.isNumber(callRecordToMqBO.getBizId())) {
                return;
            }
            // 记录小号通话记录log
            CallRecordLogDTO callRecordLogDTO = CallRecordLogDTO.builder().callerNo(callRecordToMqBO.getCallNo())
                    .callId(callRecordToMqBO.getCallId())
                    .calledNo(callRecordToMqBO.getPeerNo())
                    .callDuration(TimeUtils.getDate(callRecordToMqBO.getCallDuration()))
                    .callSustainDuration(callRecordToMqBO.getCallSustainDuration())
                    .callTime(callRecordToMqBO.getCallTime())
                    .startTime(callRecordToMqBO.getStartTime()).finishTime(callRecordToMqBO.getFinishTime())
                    .callType(callRecordToMqBO.getCallType()).calledType(callRecordToMqBO.getPeerType())
                    .xnoRecordId(callRecordToMqBO.getCallId()).xnoNo(callRecordToMqBO.getXno())
                    .hangup(FinishType.of(callRecordToMqBO.getFinishType().toString()).getName())
                    .finishState(FinishState.of(String.valueOf(callRecordToMqBO.getFinishState())).getDesc())
                    .endState(callRecordToMqBO.getFinishState())
                    .status(callRecordToMqBO.getCallStatus()).type(2).tapeUrl(callRecordToMqBO.getTapeUrl())
                    .ringDuration(callRecordToMqBO.getRingDuration())
                    .build();

            // 格式化存储小号通话记录
            logger.info("工单小号通话记录log记录[{}]", JSONObject.toJSONString(callRecordLogDTO));
            Long bizId = Long.parseLong(callRecordToMqBO.getBizId());
            Long bindId = callRecordToMqBO.getBindId();
            callRecordLogDTO.setWorkId(bizId);
            callRecordLogDTO.setOrderId(bizId);

            // 是否是临时小号通话记录
            boolean isTempXno = orderTempXnoBindBService.isTempXno(bizId, bindId);
            if (isTempXno) {
                // 补充临时小号的联系日志
                OmsOperator omsOperator = new OmsOperator();
                omsOperator.setOrderId(bizId);
                omsOperator.setWorkId(bizId);
                orderTempXnoBindBService.contactUser(omsOperator, bindId);
            } else {
                callRecordBService.processXNORecordLog(callRecordLogDTO);
                // 处理有效、无效联系工单标签
                callRecordBService.processXnoContactTag(callRecordLogDTO);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("工单小号通话记录消费 处理失败：{}", e);
        }
    }

    /**
     * 小号解绑
     *
     * @param message
     */
    @AliyunMQHandler(tags = OmsMqTagConsts.ZMN_TOPIC_XNO_UNBIND_NOTI)
    public void unBind(String message) {
        try {
            // [{"ano":"8613810005463","appKey":"oms","bindId":11305,"bizId":"2639047979767967745","bno":"8615523736306"}]
            // "ano":"8617150168302","appKey":"oms","bindId":13768,"bizId":"2690270451419766784","bno":"8618954900158","expireUnbound":true
            logger.info("XnoListener.unBind-工单解绑通知 {}", message);
            List<ZsXnoBindVO> voList = JSON.parseArray(message, ZsXnoBindVO.class);

            voList.forEach(item -> {
                Long bizId = Long.parseLong(item.getBizId());
                try {
                    // 是否是临时小号
                    boolean isTempXno = orderTempXnoBindBService.isTempXno(bizId, item.getBindId());
                    if (isTempXno) {
                        TempXnoUnBindDTO tempXnoUnBindDTO = TempXnoUnBindDTO.builder()
                                .orderId(bizId)
                                .workId(bizId)
                                .xnoBindId(item.getBindId())
                                .build();
                        orderTempXnoBindBService.unTempXnoBind(tempXnoUnBindDTO);
                        return;
                    }

                    String redisKey = String.format(RedisKeyConsts.ORDER_XNO_UNBIND_KEY, item.getBizId());
                    Boolean exists = redisManager.exists(redisKey);
                    if(exists){
                        logger.info("XnoListener.unBind-已处理工单，不需要重复解绑处理 {}", message);
                        return;
                    }
                    redisManager.setex(redisKey, String.valueOf(item.getBindId()), 120);

                    XnoUnBindDTO xnoUnBindDTO = new XnoUnBindDTO();
                    xnoUnBindDTO.setOrderId(bizId);
                    xnoUnBindDTO.setWorkId(bizId);
                    orderXnoBindBService.unBind(xnoUnBindDTO);

                    Boolean checkNeedRebind = orderXnoBindService.checkNeedRebind(xnoUnBindDTO);
                    if (checkNeedRebind) {
                        log.info("XnoListener.unBind-orderId={} workId={} 重新绑定小号", xnoUnBindDTO.getOrderId(), xnoUnBindDTO.getWorkId());
                        XnoBindDTO xnoBindDTO = new XnoBindDTO();
                        xnoBindDTO.setOrderId(xnoUnBindDTO.getOrderId());
                        xnoBindDTO.setWorkId(xnoUnBindDTO.getWorkId());
                        xnoBindDTO.setNeedBindFirstXno(true);
                        orderXnoBindBService.bind(xnoBindDTO);
                    }
                } catch (Exception e) {
                    logger.error("XnoListener.unBind-workId={} 工单解绑通知 处理失败：{}", bizId, e);
                }
            });
        } catch (Exception e) {
            logger.error("工单解绑通知 处理失败：{}", e);
        }
    }


}
